<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>回流（reflow）与重绘(repaint) | sponge</title>
    <meta name="description" content="一些很随意的前端笔记">
    <link rel="icon" href="/vuepress-blog/hero.jpg">
    
    <link rel="preload" href="/vuepress-blog/assets/css/0.styles.5d74642e.css" as="style"><link rel="preload" href="/vuepress-blog/assets/js/app.21385443.js" as="script"><link rel="preload" href="/vuepress-blog/assets/js/9.624d7ce4.js" as="script"><link rel="prefetch" href="/vuepress-blog/assets/js/10.b2b9db1b.js"><link rel="prefetch" href="/vuepress-blog/assets/js/11.fafc0e1d.js"><link rel="prefetch" href="/vuepress-blog/assets/js/12.a3867a96.js"><link rel="prefetch" href="/vuepress-blog/assets/js/13.8b18fa10.js"><link rel="prefetch" href="/vuepress-blog/assets/js/2.2e3e2c34.js"><link rel="prefetch" href="/vuepress-blog/assets/js/3.dc26014a.js"><link rel="prefetch" href="/vuepress-blog/assets/js/4.05a9910c.js"><link rel="prefetch" href="/vuepress-blog/assets/js/5.ffffdb2b.js"><link rel="prefetch" href="/vuepress-blog/assets/js/6.334e70a7.js"><link rel="prefetch" href="/vuepress-blog/assets/js/7.19b72361.js"><link rel="prefetch" href="/vuepress-blog/assets/js/8.2f20ced6.js">
    <link rel="stylesheet" href="/vuepress-blog/assets/css/0.styles.5d74642e.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/vuepress-blog/" class="home-link router-link-active"><!----> <span class="site-name">sponge</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">前端技术栈</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/vuepress-blog/jsNotes/reflow.html" class="nav-link router-link-exact-active router-link-active">笔记</a></li><li class="dropdown-item"><!----> <a href="/vuepress-blog/tips/arrSort.html" class="nav-link">其他</a></li></ul></div></div><div class="nav-item"><a href="/vuepress-blog/about.html" class="nav-link">关于我们</a></div><div class="nav-item"><a href="https://github.com/spongege" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">前端技术栈</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/vuepress-blog/jsNotes/reflow.html" class="nav-link router-link-exact-active router-link-active">笔记</a></li><li class="dropdown-item"><!----> <a href="/vuepress-blog/tips/arrSort.html" class="nav-link">其他</a></li></ul></div></div><div class="nav-item"><a href="/vuepress-blog/about.html" class="nav-link">关于我们</a></div><div class="nav-item"><a href="https://github.com/spongege" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first collapsable"><p class="sidebar-heading open"><span>jsNotes</span> <span class="arrow down"></span></p> <ul class="sidebar-group-items"><li><a href="/vuepress-blog/jsNotes/reflow.html" class="active sidebar-link">回流（reflow）与重绘(repaint)</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/vuepress-blog/jsNotes/reflow.html#浏览器的渲染过程" class="sidebar-link">浏览器的渲染过程</a></li><li class="sidebar-sub-header"><a href="/vuepress-blog/jsNotes/reflow.html#回流-reflow" class="sidebar-link">回流 reflow</a></li><li class="sidebar-sub-header"><a href="/vuepress-blog/jsNotes/reflow.html#重绘-repaint" class="sidebar-link">重绘 repaint</a></li><li class="sidebar-sub-header"><a href="/vuepress-blog/jsNotes/reflow.html#浏览器的优化机制" class="sidebar-link">浏览器的优化机制</a></li><li class="sidebar-sub-header"><a href="/vuepress-blog/jsNotes/reflow.html#减少回流和重绘" class="sidebar-link">减少回流和重绘</a></li><li class="sidebar-sub-header"><a href="/vuepress-blog/jsNotes/reflow.html#参考" class="sidebar-link">参考</a></li></ul></li><li><a href="/vuepress-blog/jsNotes/reg.html" class="sidebar-link">正则</a></li><li><a href="/vuepress-blog/jsNotes/arrSort.html" class="sidebar-link">数组排序</a></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="回流（reflow）与重绘-repaint"><a href="#回流（reflow）与重绘-repaint" aria-hidden="true" class="header-anchor">#</a> 回流（reflow）与重绘(repaint)</h1> <h2 id="浏览器的渲染过程"><a href="#浏览器的渲染过程" aria-hidden="true" class="header-anchor">#</a> 浏览器的渲染过程</h2> <p>在了解回流与重绘之前，我们先大概了解一下浏览器的渲染过程，如图（来自<a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=zh-cn" target="_blank" rel="noopener noreferrer">mdn<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>）:
<img src="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/images/render-tree-construction.png?hl=zh-cn" alt="生成渲染树"></p> <blockquote><p>渲染过程如下：</p></blockquote> <ol><li><p>解析 HTML，生成 DOM 树，解析 CSS，生成 CSSOM 树,</p></li> <li><p>将 DOM 树和 CSSOM 树结合，生成渲染树(Render Tree)，为构建渲染树，浏览器大体上完成了下列工作：</p> <p>2.1 从 DOM 树的根节点开始遍历每个可见节点。（不可见节点包括一些不会渲染输出的节点，比如 script、meta、link 等，以及一些通过 css 进行隐藏的节点。比如 display:none）<br>
2.2 对于每个可见节点，为其找到适配的 CSSOM 规则并应用它们。<br>
2.3 发射可见节点，连同其内容和计算的样式。</p></li> <li><p>Layout(回流):根据生成的渲染树，进行回流(Layout)，得到节点的几何信息（位置，大小）</p></li> <li><p>Painting(重绘):根据渲染树以及回流得到的几何信息，得到节点的绝对像素</p></li> <li><p>Display:将像素发送给 GPU，展示在页面上。</p></li></ol> <h2 id="回流-reflow"><a href="#回流-reflow" aria-hidden="true" class="header-anchor">#</a> 回流 reflow</h2> <p>回流又称为重排，指的是浏览器为了重新渲染文档而重新计算文档中元素的位置和几何结构的过程，简单来说就是当页面布局或者几何属性改变时就需要回流。回流阶段是计算 DOM 在视口内位置和大小的阶段。</p> <blockquote><p>当渲染树的一部分或全部的元素因改变了自身的宽高，布局，显示或隐藏，或者元素内部的文字结构（图片内容以及应用广泛的输入控件内容）发生变化 导致需要重新构建页面的时候，或者添加删除 dom 以及改变浏览器的窗口的时候，或者计算读取元素的 offsetWidth 等，都会产生回流。</p></blockquote> <h2 id="重绘-repaint"><a href="#重绘-repaint" aria-hidden="true" class="header-anchor">#</a> 重绘 repaint</h2> <p>重绘是知道 DOM 确定位置和大小后，将渲染树的每个节点都转换为屏幕上的实际像素的过程。</p> <blockquote><p>当一个元素自身的宽高，布局，及显示或隐藏没有改变，而只是改变了元素的样式风格相关的属性的时候，就会产生重绘。</p></blockquote> <p><strong><em>回流必定触发重绘，而重绘不一定触发回流</em></strong></p> <h2 id="浏览器的优化机制"><a href="#浏览器的优化机制" aria-hidden="true" class="header-anchor">#</a> 浏览器的优化机制</h2> <p>由于回流会造成额外计算的消耗，所以大多数浏览器都会收集 reflow 操作到缓存队列中，直到过了一段时间或者操作达到了一个阈值，才一次性地清空队列，反馈到渲染树中。但是<strong>当你获取布局信息的操作的时候，会强制队列刷新</strong>，比如当你访问以下属性或者使用以下方法：</p> <ul><li><code>offsetTop、offsetLeft、offsetWidth、offsetHeight</code></li> <li><code>scrollTop、scrollLeft、scrollWidth、scrollHeight</code></li> <li><code>clientTop、clientLeft、clientWidth、clientHeight</code></li> <li><code>getComputedStyle() 或者 currentStyle() (IE)</code></li> <li><code>getBoundingClientRect</code></li> <li><a href="https://link.juejin.im/?target=https%3A%2F%2Fgist.github.com%2Fpaulirish%2F5d52fb081b3570c81e3a" target="_blank" rel="noopener noreferrer">其他的一些操作<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <p>以上属性和方法都需要返回最新的布局信息，因此浏览器不得不清空队列，触发回流重绘来返回正确的值。因此，我们在修改样式的时候，<strong>最好避免使用上面列出的属性，他们都会刷新渲染队列</strong>。如果要使用它们，<strong>最好将值缓存起来</strong>。</p> <p>了解有哪些属性值改变会触发回流或者重绘点击<a href="https://csstriggers.com/" target="_blank" rel="noopener noreferrer">这里<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h2 id="减少回流和重绘"><a href="#减少回流和重绘" aria-hidden="true" class="header-anchor">#</a> 减少回流和重绘</h2> <h3 id="_1、尽量使用-flexbox-而不是较早的布局模型，可以大大缩减回流的时间。"><a href="#_1、尽量使用-flexbox-而不是较早的布局模型，可以大大缩减回流的时间。" aria-hidden="true" class="header-anchor">#</a> 1、尽量使用 flexbox 而不是较早的布局模型，可以大大缩减回流的时间。</h3> <h3 id="_2、对频繁发生回流的元素做特殊处理"><a href="#_2、对频繁发生回流的元素做特殊处理" aria-hidden="true" class="header-anchor">#</a> 2、对频繁发生回流的元素做特殊处理</h3> <ul><li>使用 <code>DocumentFragment</code> 进行缓存操作,引发一次回流和重绘；</li> <li>使用 <code>display:none</code>，只引发两次回流和重绘；</li> <li>使用 <code>cloneNode(true or false)</code> 和 <code>replaceChild</code> 技术，引发一次回流和重绘；</li></ul> <p>Dom 规定文档片段（document fragment）是一种“轻量级”的文档，可以包含和控制节点，但不会想完整的文档那样占用额外的资源。虽然不能把文档片段直接添加到文档中，但是可以将它作为一个“仓库”来使用，即可以在里面保存将来可能会添加到文档中的节点。
比如最开始的样例结合 DocumentFragment 就可以这样写：</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'DOMContentLoaded'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    fragment <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createDocumentFragment</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">7000</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> tmpNode <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span>
    tmpNode<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">'test'</span> <span class="token operator">+</span> i
    fragment<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>tmpNode<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>fragment<span class="token punctuation">)</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'speed time'</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> date<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>将多个修改结果收纳到了 documentFragment 这个“仓库”中，这个过程并不会影响到 render tree，待循环完毕再将这个“仓库”的“存货”添加到 dom 上，以此达到减少 reflow 的目的，使用 cloneNode 也是同理。
而使用 display：none 来降低 reflow 的性能开销的原理在于使节点从 render tree 中失效，等经过多个会触发 reflow 操作后再“上线”。</p> <h3 id="_3、避免强制同步布局"><a href="#_3、避免强制同步布局" aria-hidden="true" class="header-anchor">#</a> 3、避免强制同步布局</h3> <p>首先 JavaScript 运行，然后计算样式，然后布局。但是，可以使用 JavaScript 强制浏览器提前执行布局。这被称为强制同步布局。
要记住的第一件事是，在 JavaScript 运行时，来自上一帧的所有旧布局值是已知的，并且可供您查询。因此，如果（例如）您要在帧的开头写出一个元素（让我们称其为“框”）的高度，可能编写一些如下代码：</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">getHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  box<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">)</span>

  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>box<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>现在，为了回答高度问题，浏览器必须先应用样式更改（由于增加了 super-big 类），然后运行布局。这时它才能返回正确的高度。这是不必要的，并且可能是开销很大的工作。</p> <p>因此，始终应先批量读取样式并执行（浏览器可以使用上一帧的布局值），然后执行任何写操作：</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">getHeight</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>box<span class="token punctuation">.</span>offsetHeight<span class="token punctuation">)</span> <span class="token comment">// 先读取后执行更改</span>

  box<span class="token punctuation">.</span>classList<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>大部分情况下，并不需要应用样式然后查询值；使用上一帧的值就足够了。与浏览器同步（或比其提前）运行样式计算和布局可能成为瓶颈，并且您一般不想做这种设计</p> <h3 id="_4、避免布局抖动"><a href="#_4、避免布局抖动" aria-hidden="true" class="header-anchor">#</a> 4、避免布局抖动</h3> <p>当我们访问元素的一些属性的时候，会导致浏览器强制清空队列，进行强制同步布局，我们也能会写如下的业务代码：</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> box<span class="token punctuation">.</span>offsetWidth <span class="token operator">+</span> <span class="token string">'px'</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>此时就会造成很大的性能开销，每次循环都会获取<code>box</code>的<code>offsetWidth</code>，造成回流，导致<strong>每一次循环都会强制浏览器刷新队列</strong>，我们可以做如下优化：</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">const</span> width <span class="token operator">=</span> box<span class="token punctuation">.</span>offsetWidth <span class="token comment">// 依旧遵循先读取执行更改</span>
<span class="token keyword">function</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    arr<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> width <span class="token operator">+</span> <span class="token string">'px'</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="_5、对于复杂动画效果-使用绝对定位让其脱离文档流"><a href="#_5、对于复杂动画效果-使用绝对定位让其脱离文档流" aria-hidden="true" class="header-anchor">#</a> 5、对于复杂动画效果,使用绝对定位让其脱离文档流</h3> <h3 id="_6、css3-硬件加速（gpu-加速）"><a href="#_6、css3-硬件加速（gpu-加速）" aria-hidden="true" class="header-anchor">#</a> 6、css3 硬件加速（GPU 加速）</h3> <ul><li><p>用 translate 代替 top，用 opacity 替代 visibility</p></li> <li><p>使用 css3 硬件加速，可以让 <code>transform、opacity、filters</code> 这些动画不会引起回流重绘 。</p></li> <li><p>对于动画的其它属性，比如 <code>background-color</code> 这些，还是会引起回流重绘的，不过它还是可以提升这些动画的性能。</p></li></ul> <p>常见的触发硬件加速的 <code>css</code> 属性：</p> <ul><li><code>transform</code></li> <li><code>opacity</code></li> <li><code>filters</code></li> <li><code>Will-change</code></li></ul> <p>重点</p> <ul><li>使用 css3 硬件加速，可以让<code>transform、opacity、filters</code>这些动画不会引起回流重绘</li> <li>对于动画的其它属性，比如<code>background-color</code>这些，还是会引起回流重绘的，不过它还是可以提升这些动画的性能</li></ul> <h2 id="参考"><a href="#参考" aria-hidden="true" class="header-anchor">#</a> 参考</h2> <ul><li><a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=zh-cn" target="_blank" rel="noopener noreferrer">渲染树构建、布局及绘制<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts" target="_blank" rel="noopener noreferrer">避免大型、复杂的布局和布局抖动<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://juejin.im/post/5c6cb7b4f265da2dae511a3d" target="_blank" rel="noopener noreferrer">你真的了解回流和重绘吗<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://juejin.im/post/5a9372895188257a6b06132e#heading-11" target="_blank" rel="noopener noreferrer">reflow 和 repaint 引发的性能问题<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></div> <div class="page-edit"><!----> <!----></div> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/vuepress-blog/jsNotes/reg.html">
          正则
        </a>
        →
      </span></p></div> </div> <div class="page"><section class="page-edit"><div><span data-flag-title="Your Article Title" class="leancloud-visitors"><em class="post-meta-item-text">阅读量： </em> <i class="leancloud-visitors-count"></i></span></div> <h3><a href="javascript:;"></a>
      评 论：
    </h3> <div id="vcomments"></div></section></div> <!----></div></div>
    <script src="/vuepress-blog/assets/js/app.21385443.js" defer></script><script src="/vuepress-blog/assets/js/9.624d7ce4.js" defer></script>
  </body>
</html>
